#include<pthread.h>
#include<stdio.h>
#include<semaphore.h>
#define false 0
#define true 1
#define P_NUMBER 10 //并发线程数量
#define PRODUCE_SPEED 2
#define CONSUME_SPEED 1
#define MAX 5
int flag[2];
int turn;
sem_t empty;//生产者私有信号量，表示空缓冲区数目
sem_t full;//消费者私有变量，表示有产品的缓冲区数目
//生产者进程
int now_num =0;//初始化仓库为空
void * producer(){
    sleep(PRODUCE_SPEED);//生产时间
        sem_wait(&empty);//申请空缓冲区，P操作
        flag[0] = true;
        turn = 1;
        //申请队列互斥
        while(flag[1] &&  turn ==1);
            now_num++;
			printf("生产者成功进入了临界区，放入了一个产品，当前产品数目为%d\n",now_num);
			flag[0] = false;
            sem_post(&full);//释放满缓冲区，V操作
			printf("生产者退出了缓冲区\n");
        pthread_exit(NULL);
			}
//消费者进程
	void * consumer(){
		
            sleep(CONSUME_SPEED);//消费时间
			flag[1]=true;
			turn = 0;
            sem_wait(&full);//申请满缓冲区，P操作
            while(flag[0] && turn ==0);
            now_num--;
			printf("消费者成功进入了临界区，拿走了产品，当前的产品数目为%d\n",now_num);
			flag[1] = false;
            sem_post(&empty);//释放空缓冲区，V操作
			printf("消费者退出了缓冲区\n");
            pthread_exit(NULL);
		
	}

	int main(){
        //初始化
        int init1 = sem_init(&empty,0,MAX);//第二个参数表示进程内线程共享
        int init2 = sem_init(&full,0,0);
        if(init1 ==-1 || init2 ==-1){
            printf("出错了");
        }
		flag[0]=flag[1]=false;
		pthread_t consume[P_NUMBER];//消费者线程数组
        pthread_t produce[P_NUMBER];//生产者线程数组
		int i = 0;
        for(;i<P_NUMBER;i++){
            //创建生产者线程
            int j = pthread_create(&produce[i],NULL,(void *)producer,NULL);
            sleep(1);
            if(j!=0){
                printf("生产者线程创建失败");
            }
        }
        i=0;
        for(;i<P_NUMBER;i++){
            //创建消费者线程
            int j = pthread_create(&consume[i],NULL,(void *)consumer,NULL);
            sleep(1);
            if(j!=0){
                printf("生产者线程创建失败");
            }
        }
        i=0;
		for(;i<P_NUMBER;i++){
			pthread_join(consume[i],NULL);//回收线程
            pthread_join(produce[i],NULL);
		}
		return 0;
	}
